//  Inside Microsoft Exchange 2007 Web Services 
//  Chapter 10
//
//  Copyright (c) 2007 David Sterling, Ben Spain, Mark Taylor, Huw Upshall, Michael Mainer.  
//  All rights reserved.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using ProxyHelpers.EWS;

namespace UpdateCalendarItemToMeeting
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeServiceBinding binding = new ExchangeServiceBinding();
            binding.Url = @"https://yourServer/ews/Exchange.asmx";
            binding.Credentials = new NetworkCredential(
                "username",
                "password",
                "domain");

            // TODO: You must have the itemId of a calendar item you want to turn into a meeting before
            // calling UpdateCalendarItemToMeeting.
        }

        /// <summary>
        /// Updates an existing calendar item, turning it into a meeting
        /// and sends invitations to all attendees (Listing 10-5)
        /// </summary>
        /// <param name="binding">Binding to use for the web service call</param>
        /// <param name="existingCalendarItem">Id of the existing calendar item</param>
        /// <param name="newRequiredAttendees">All required attendees</param>
        /// <param name="newOptionalAttendees">All optional attendees</param>
        /// <param name="meetingRoom">Meeting room location</param>
        /// <returns>Id of updated meeting</returns>
        /// 
        public static ItemIdType UpdateCalendarItemToMeeting(
            ExchangeServiceBinding binding,
            ItemIdType existingCalendarItem,
            EmailAddressType[] newRequiredAttendees,
            EmailAddressType[] newOptionalAttendees,
            EmailAddressType meetingRoom)
        {
            // Create a collection to store all
            // AppendToItemFieldType instances that
            // may be needed.
            //
            List<AppendToItemFieldType> appendToItemObjects =
                new List<AppendToItemFieldType>();

            // Create an AppendToItemFieldType instance for
            // required attendees.
            //
            if (newRequiredAttendees != null &&
                newRequiredAttendees.Length > 0)
            {
                List<AttendeeType> reqAttendees = new List<AttendeeType>();
                foreach (EmailAddressType attendeeEmailInfo in newRequiredAttendees)
                {
                    AttendeeType reqAttendee = new AttendeeType();
                    reqAttendee.Mailbox = attendeeEmailInfo;
                    reqAttendees.Add(reqAttendee);
                }

                CalendarItemType calItemForReqAttendees = new CalendarItemType();
                calItemForReqAttendees.RequiredAttendees =
                    reqAttendees.ToArray();

                PathToUnindexedFieldType fieldURI = new PathToUnindexedFieldType();
                fieldURI.FieldURI = UnindexedFieldURIType.calendarRequiredAttendees;

                AppendToItemFieldType reqAttendeesAppend = new AppendToItemFieldType();
                reqAttendeesAppend.Item = fieldURI;
                reqAttendeesAppend.Item1 = calItemForReqAttendees;
                appendToItemObjects.Add(reqAttendeesAppend);
            }

            // Create an AppendToItemFieldType instance for
            // optional attendees.
            //
            if (newOptionalAttendees != null &&
                newOptionalAttendees.Length > 0)
            {
                List<AttendeeType> optAttendees = new List<AttendeeType>();
                foreach (EmailAddressType attendeeEmailInfo in newOptionalAttendees)
                {
                    AttendeeType optAttendee = new AttendeeType();
                    optAttendee.Mailbox = attendeeEmailInfo;
                    optAttendees.Add(optAttendee);
                }

                CalendarItemType calItemForOptAttendees = new CalendarItemType();
                calItemForOptAttendees.OptionalAttendees =
                    optAttendees.ToArray();

                PathToUnindexedFieldType fieldURI = new PathToUnindexedFieldType();
                fieldURI.FieldURI = UnindexedFieldURIType.calendarOptionalAttendees;

                AppendToItemFieldType optAttendeesAppend = new AppendToItemFieldType();
                optAttendeesAppend.Item = fieldURI;
                optAttendeesAppend.Item1 = calItemForOptAttendees;
                appendToItemObjects.Add(optAttendeesAppend);
            }

            // Create an AppendToItemFieldType instance for
            // resources.
            //
            if (meetingRoom != null)
            {
                AttendeeType meetingRoomAttendeeInfo = new AttendeeType();
                meetingRoomAttendeeInfo.Mailbox = meetingRoom;

                CalendarItemType calItemForResources = new CalendarItemType();
                calItemForResources.Resources =
                    new AttendeeType[] { meetingRoomAttendeeInfo };

                PathToUnindexedFieldType fieldURI = new PathToUnindexedFieldType();
                fieldURI.FieldURI = UnindexedFieldURIType.calendarResources;

                AppendToItemFieldType resourcesAppend = new AppendToItemFieldType();
                resourcesAppend.Item = fieldURI;
                resourcesAppend.Item1 = calItemForResources;
                appendToItemObjects.Add(resourcesAppend);
            }

            // Throw an exception if there are no changes needed
            //
            if (appendToItemObjects.Count == 0)
            {
                throw new Exception(
                    "There were no attendees in any attendee collection.");
            }

            // Create an ItemChangeType instance to hold all the updates
            //
            ItemChangeType itemChangeInfo = new ItemChangeType();
            itemChangeInfo.Item = existingCalendarItem;
            itemChangeInfo.Updates = appendToItemObjects.ToArray();

            // Assemble the UpdateItem request
            //
            UpdateItemType updateItemRequest = new UpdateItemType();
            updateItemRequest.ConflictResolution = ConflictResolutionType.AutoResolve;
            updateItemRequest.SendMeetingInvitationsOrCancellations =
                CalendarItemUpdateOperationType.SendOnlyToAll;
            updateItemRequest.SendMeetingInvitationsOrCancellationsSpecified = true;
            updateItemRequest.ItemChanges = new ItemChangeType[] { itemChangeInfo };

            // Call the UpdateItem web method via the Exchange Serivce Binding
            UpdateItemResponseType updateItemResponse =
                binding.UpdateItem(updateItemRequest);

            // Verify that the UpdateItem request was successful
            if (updateItemResponse.ResponseMessages.Items[0].ResponseClass !=
                ResponseClassType.Success)
            {
                // Indicate that we have a problem
                throw new Exception(String.Format(
                    "Unable to update calendar item\r\n{0}\r\n{1}",
                    updateItemResponse.ResponseMessages.Items[0].ResponseCode,
                    updateItemResponse.ResponseMessages.Items[0].MessageText));
            }

            // Success, get the updated id of meeting
            ItemInfoResponseMessageType itemInfoResponseMessage =
                (ItemInfoResponseMessageType)updateItemResponse.
                    ResponseMessages.Items[0];

            return itemInfoResponseMessage.Items.Items[0].ItemId;
        }

    }
}
